Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): support custom description for blog-only mode #2359

Merged
merged 7 commits into from
Jul 30, 2020

Conversation

zxuqian
Copy link
Contributor

@zxuqian zxuqian commented Mar 5, 2020

Motivation

In blog-only mode, the meta description is set to "Blog", which leads to poor SEO. The custom homepage under src/pages/index.js uses the value of a customFields.descriptionfield defined in docusaurus.config.js to display the description. In this PR, I use the same customFields.description config value for the BlogPostList component in the docusaurus-theme-classic theme.

Have you read the Contributing Guidelines on pull requests?

Yes.

Test Plan

  1. In docusaurus.config.js, look at the customFields.description value:
customFields: {
    description:
      'An optimized site generator in React. Docusaurus helps you to move fast and write content. Build documentation websites, blogs, marketing pages, and more.',
  }
  1. Set the site to blog-only mode by setting routeBasePath to '/' in presets
presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          path: '../website-1.x/blog',
          postsPerPage: 3,
          feedOptions: {
            type: 'all',
            copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`,
          },
        },
      },
    ],
  ]
  1. Check rendered page, the meta description displays the description value defined in customFields:

image

Related PRs

(If this PR adds or changes functionality, please take some time to update the docs at https://github.com/facebook/docusaurus, and link to your PR here.)

@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Mar 5, 2020
@docusaurus-bot
Copy link
Contributor

docusaurus-bot commented Mar 5, 2020

Deploy preview for docusaurus-2 ready!

Built with commit 77bacef

https://deploy-preview-2359--docusaurus-2.netlify.app

Copy link
Contributor

@yangshun yangshun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good API design. We shouldn't use customFields for a first-class feature. I don't have a good way around this right now but using the siteConfig's description would be better. Ideally we allow setting it on the blog plugin but there's no easy way to pass data from the blog plugin to the front end right now.

@zxuqian
Copy link
Contributor Author

zxuqian commented Mar 6, 2020

OK. I will rename it to description and extract it from top level config (same level as title). This is what you mean, right😃?

Is it the ideal way to let the user write a description for each post at the header option in the markdown file, and set the whole site's description in the blog config under preset-classic?

@zxuqian
Copy link
Contributor Author

zxuqian commented Mar 6, 2020

Ideally we allow setting it on the blog plugin but there's no easy way to pass data from the blog plugin to the front end right now.

By examining the source code, I found that the components are dynamically loaded by their filenames. The metadata and items properties in blogListPaginated are written to a JSON file and then loaded in the ComponentCreator. The components routes are dynamically created and the ComponentCreator is called inside the dynamically created route.js file in the build folder. I think we can pass additional routeProps to the ComponentCreator.

Here I made some changes (I would consider they are a little bit big.., but you can help me to review it 🤔 ..), here is the description of the major changes I have made:

  1. Here I added a second parameter routeProps in ComponentCreator, and pass it to the Component loaded:
function ComponentCreator(path, routeProps) {
    //...
    return <Component {...loadedModules} {...props} {...routeProps} />;
  1. In the docusaurs/src/routes.ts, the generateRouteCode function, the routeConfig now added a new property called props, and it will be passed to ComponentCreator:
function generateRouteCode(routeConfig: RouteConfig): string {
    const {
      path: routePath,
      component,
      modules = {},
      routes,
      exact,
      props,
    } = routeConfig;
    //...
    return `
{
  path: '${routePath}',
  component: ComponentCreator('${routePath}'${
      props ? `, ${JSON.stringify(props)}` : ''
    }),
  ${exactStr}
  ${routesStr}
}`;
  }
  1. When call addRoute in the docusaurus-plugin-content-blog/index.ts, pass the additional props to the routeConfig, here I'm using a blogSiteDescription which is extracted from the plugin configuration, and its default value is "Blog":
addRoute({
            path: permalink,
            component: blogListComponent,
            exact: true,
            modules: {...},
            props: {
              blogSiteDescription,
            },
          });

I would update the code, so you can have a review of it.

@zxuqian zxuqian requested a review from yangshun March 6, 2020 15:21
@yangshun yangshun added the pr: new feature This PR adds a new API or behavior. label Mar 7, 2020
@slorber
Copy link
Collaborator

slorber commented Jul 28, 2020

@zxuqian this feature makes sense to me, can you update your pr?

Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

willing to merge but need:

  • rebase
  • remove the "routeProps" system (un-needed)
  • rename blogSiteDescription to blogDescription
  • document

@@ -149,6 +149,7 @@ export interface RouteConfig {
routes?: RouteConfig[];
exact?: boolean;
priority?: number;
props?: object;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

@@ -43,6 +43,7 @@ const DEFAULT_OPTIONS: PluginOptions = {
remarkPlugins: [],
rehypePlugins: [],
truncateMarker: /<!--\s*(truncate)\s*-->/, // Regex.
blogSiteDescription: 'Blog',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blogDescription seems a better name (+ we need documentation)

@@ -285,6 +287,9 @@ export default function pluginContentBlog(
}),
metadata: aliasedSource(pageMetadataPath),
},
props: {
blogSiteDescription,
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need that, you'll already receive metadata.blogDescription as props

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @slorber , I found that to use blogDescription in metadata, I still need to get it from options object and pass it to the metadata object here(about line 125):

metadata: {
        permalink: blogPaginationPermalink(page),
        page: page + 1,
        postsPerPage,
        totalPages: numberOfPages,
        totalCount,
        previousPage: page !== 0 ? blogPaginationPermalink(page - 1) : null,
        nextPage:
          page < numberOfPages - 1
                ? blogPaginationPermalink(page + 1)
                : null,
        blogDescription: options.blogDescription,
}

Could you tell me if this is the case? Thank you!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the blogDescription is a field on the plugin options

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK! Thanks.

@@ -13,15 +13,14 @@ import BlogPostItem from '@theme/BlogPostItem';
import BlogListPaginator from '@theme/BlogListPaginator';

function BlogListPage(props) {
const {metadata, items} = props;
const {metadata, items, blogSiteDescription} = props;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use metadata.blogDescription

component: ComponentCreator('${routePath}'),
component: ComponentCreator('${routePath}'${
props ? `, ${JSON.stringify(props)}` : ''
}),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

@@ -77,7 +77,7 @@ function ComponentCreator(path) {

const Component = loadedModules.component;
delete loadedModules.component;
return <Component {...loadedModules} {...props} />;
return <Component {...loadedModules} {...props} {...routeProps} />;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

@@ -51,6 +51,7 @@ module.exports = {
type: 'all',
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`,
},
blogSiteDescription: 'Test description....',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove to be able to merge

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I leave blogDescription inside blog config, or should I move it to the root?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's in the blog options, because a Docusaurus might support hosting multiple blogs in the future, each one having its own description

@zxuqian
Copy link
Contributor Author

zxuqian commented Jul 29, 2020

OK! I will update it

@slorber slorber marked this pull request as draft July 29, 2020 17:39
@zxuqian zxuqian marked this pull request as ready for review July 30, 2020 04:53
@zxuqian zxuqian requested review from slorber and removed request for wgao19 July 30, 2020 10:12
Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good, just a few things to change

@@ -20,6 +20,7 @@ export const DEFAULT_OPTIONS = {
blogTagsListComponent: '@theme/BlogTagsListPage',
blogPostComponent: '@theme/BlogPostPage',
blogListComponent: '@theme/BlogListPage',
blogDescription: '',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
blogDescription: '',
blogDescription: 'Blog',

Let's keep it retrocompatible, it displays Blog by default currently

<Layout title={title} description="Blog">
<div className="container margin-vert--lg">
<Layout title={title} description={blogDescription}>
<div className="container margin-vert--xl">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div className="container margin-vert--xl">
<div className="container margin-vert--lg">

It's not the purpose of this PR to change the design. I'm open to discussing this but in another PR.

I think it looks weird on mobile to have as much

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh! This might be accidentally merged from a conflict, I will correct it.

'@docusaurus/preset-classic',
{
blog: {
blogDescription: 'A docusuarus powered blog!',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
blogDescription: 'A docusuarus powered blog!',
blogDescription: 'A docusaurus powered blog!',

/**
* Blog page meta description for better SEO
*/
blogDescription: '',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
blogDescription: '',
blogDescription: 'Blog',

@slorber
Copy link
Collaborator

slorber commented Jul 30, 2020

Looks good, ready to merge, thanks

@slorber slorber merged commit 4af25cd into facebook:master Jul 30, 2020
@zxuqian
Copy link
Contributor Author

zxuqian commented Jul 30, 2020

No problem, and thank you for the reviews!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Signed Facebook CLA pr: new feature This PR adds a new API or behavior.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants